#ifndef FRAME_H
#define FRAME_H

#include <netinet/in.h>
#include <sys/types.h>


static const unsigned short QUIMERA_PORT=707;

static char version=1;

static const long IC=1;
static const long MC=2;
static const long GC=3;
static const long AP=4;
static const long MR=5;
static const long GR=6;
static const long I=7;
static const long M=8;
static const long B=9;
static const long CLR=30;
static const long CLRU=35;

static const int S_PACKER_QUEUE_KEY=23;
static const int S_UNPACKER_QUEUE_KEY=76;
static const int C_PACKER_QUEUE_KEY=32;
static const int C_UNPACKER_QUEUE_KEY=67;
static const int I_QUEUE_KEY=100;
static const int LOGGER_QUEUE_KEY=22;
static const int API_QUEUE_KEY=61;


static const unsigned char BOOKMARK=0x99;
static const unsigned char MEMBERSHIP=0x01;
static const unsigned char INVESTMENT=0xFF;
static const unsigned char INVESTMENT_CONFIRMATION=0x15;
static const unsigned char GUARD_REPORT=0xF0;
static const unsigned char GUARD_CONFIRMATION=0x0F;
static const unsigned char MISSING_REPORT=0x07;
static const unsigned char MISSING_CONFIRMATION=0x70;
static const unsigned char ADOPTION_PAPERS=0x0A;

static const int LOG_QUEUE_ERR_LOG=0;
static const int LOG_QUEUE_ERR_UNPACKER=1;
static const int LOG_QUEUE_EVNT_UNPACKER=2;
static const int LOG_QUEUE_EVNT_IN_INVESTMENT=103;
static const int LOG_QUEUE_EVNT_IN_GC=104;
static const int LOG_QUEUE_EVNT_IN_MC=105;
static const int LOG_QUEUE_EVNT_IN_ADOPTIONP=106;
static const int LOG_QUEUE_EVNT_IN_BOOKMARK=107;
static const int LOG_QUEUE_EVNT_IN_UNKNOWN=108;
static const int LOG_QUEUE_ERR_IN_UNPACKER=10;
static const int LOG_QUEUE_EVNT_GUARD=111;
static const int LOG_QUEUE_EVNT_MISSING=112;
static const int LOG_QUEUE_EVNT_IN_MEMBERSHIP=113;
static const int LOG_QUEUE_EVNT_IN_GUARD_REPORT=114;
static const int LOG_QUEUE_EVNT_IN_MISSING_REPORT=115;
static const int LOG_QUEUE_EVNT_IN_INVESTMENT_C=116;
static const int LOG_QUEUE_ERR_UNPACKER_QCP=117;
static const int LOG_QUEUE_EVNT_OUT_MEMBERSHIP=118;
static const int LOG_QUEUE_ENVT_CONNECT=19;
static const int LOG_QUEUE_ERR_TIMEOUT=20;
static const int LOG_QUEUE_ERR_OUT_SEND=121;
static const int LOG_QUEUE_ERR_TOUCH=22;
static const int LOG_QUEUE_ERR_POOL=23;
static const int LOG_QUEUE_EVNT_CREGISTER=1024;
static const int LOG_QUEUE_ERR_UNPACKER_QSP=25;
static const int LOG_QUEUE_EVNT_OUT_INVESTMENT=126;
static const int LOG_QUEUE_EVNT_OUT_INVESTMENT_C=127;
static const int LOG_QUEUE_EVNT_CLOGOUT=1028;
static const int LOG_QUEUE_ERR_SKILLER=29;
static const int LOG_QUEUE_EVNT_OUT_GUARD=130;
static const int LOG_QUEUE_EVNT_OUT_MISSING=131;
static const int LOG_QUEUE_EVNT_OUT_GUARD_C=132;
static const int LOG_QUEUE_EVNT_OUT_MISSING_C=133;
static const int LOG_QUEUE_EVNT_OUT_ADOPTION_P=134;
static const int LOG_QUEUE_ERR_IN_REPLY=135;
static const int LOG_QUEUE_EVNT_EXPIRE=136;
static const int LOG_QUEUE_ERR_CKILLER=38;
static const int LOG_QUEUE_EVNT_CLEAR=99;




typedef struct Payload{
        unsigned int                     size;
        void                            *buff;
}Buffer;

typedef struct Header{ 
        char                            version;
        unsigned char                   domain;
        unsigned char                   type_message;
        unsigned int                    n_register;
        unsigned int                    id_server_source;
        unsigned int                    id_server_destination;
        char                            flag;
        unsigned short                  offset;
}Header;
 
typedef struct Package{
        Header                          header;
        unsigned short                  f_time;
        struct sockaddr_in              id_client; 
        unsigned int                    sequence_number;
        unsigned int                    acknowledge_number;
        unsigned int                    next_sequence_number;
        unsigned int                    id_server_guardian;
        struct sockaddr_in              ip_server_guardian;
}Package;

typedef struct Book_msg{
    Package p;
    char payload[1];  
}Book;


typedef struct Message_queue{
        long                            id_message;
        Package                         package;
        struct sockaddr_in              cli_addr;
}Message_queue; 

int Message_queue_setup(const int);

class Message
{
public:
    
    Header                          hdr;    
    Package                         pkg;
    Book*                           packet;   
    static unsigned int             n_register;
    static const unsigned char      NULL_MESSAGE_TYPE=0xAA;
    static const char               NO_FLAG=0;
    static const char               U_FLAG=0xFF;
    static const unsigned short     NO_OFFSET=0;
    
    Message();
    virtual ~Message();
    
    virtual void Fill_header(unsigned char&, unsigned int&, unsigned int&);
    
    virtual void Membership();
    
    virtual void Investment(unsigned short&);
    
    virtual void Guard_report(struct sockaddr_in &);
    
    virtual void Missing_report(struct sockaddr_in &, unsigned int&, unsigned int&,
                   unsigned int&);
    
    virtual void Adoption_papers(struct sockaddr_in &, unsigned int&, unsigned int&,
                   unsigned int&,struct sockaddr_in &, unsigned int&);
    
    virtual void Bookmark(struct sockaddr_in &, unsigned int&, unsigned int&,
             unsigned int&,struct sockaddr_in &, unsigned int&, Buffer&);
    
    virtual void Confirmation(Package &);
    
    virtual unsigned int Get_n_register();
    
};


#endif	/* Frame*/

